package com.ls.config.shiro;

import com.ls.constant.SystemConstants;
import com.ls.entity.SysPermission;
import com.ls.service.ISysPermissionService;
import com.ls.utils.redis.RedisClient;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import static com.ls.utils.redis.RedisKey.ROLE_PERMISSION_KEY;


/**
 * @ClassName ShiroRealm
 * @Description shiro验证类
 * @Author YangLei
 * @Date 2019/5/7 10:37
 * @Version 1.0
 **/
public class ShiroRealm  extends AuthorizingRealm {
    private static final Logger LOGGER = LoggerFactory.getLogger(ShiroRealm.class);

    @Autowired
    private ISysPermissionService sysPermissionService;
    @Autowired
    private RedisClient redisClient;

    /**
     * 权限认证
     * @param principalCollection PrincipalCollection
     * @return AuthorizationInfo
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        Subject subject = SecurityUtils.getSubject();
        Long roleId = (Long)subject.getSession().getAttribute(SystemConstants.SESSION_USER_ROLE_ID);
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        // 查询用户拥有的权限并交给shiro框架
        List<SysPermission> permissions = redisClient.getList(ROLE_PERMISSION_KEY, String.valueOf(roleId),SysPermission.class);
        if(permissions==null || permissions.size() ==0){
            LOGGER.error("缓存角色权限出现问题");
            permissions =  sysPermissionService.findPermissionsByRoleId(roleId);
        }
        Set<String> sns = new HashSet<>();
        for (SysPermission permission : permissions) {
            if (null == permission || StringUtils.isEmpty(permission.getSn())) {
                continue;
            }
            sns.add(permission.getSn());
        }
        info.addStringPermissions(sns);
        return info;
    }

    /**
     * 获取身份验证信息
     * @param token 用户身份信息 token
     * @return 回封装了用户信息的 AuthenticationInfo 实例
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken)token;
        //账号
        String account = (String)usernamePasswordToken.getPrincipal();
        char[] pwd = usernamePasswordToken.getPassword();
        StringBuilder sb = new StringBuilder();
        for (char c : pwd) {
            sb.append(c);
        }
        // 认证密码
        Object password = sb.toString();
        // 框架进行登录判断
        return new SimpleAuthenticationInfo(account, password, getName());
    }
}
